import {computed, reactive, nextTick} from 'vue'
import _ from 'lodash'

interface FocusSuite {
  // 注册
  regRef: (el: any, index: number) => void
  // 按了回车
  onEntered: (index: number) => void
  // 聚焦到第一个input
  focusFirst: () => void
}

/**
 * 初始化Focus链并返回帮助方法
 * @param onLastEntered Focus链的最后一个元素上敲了回车
 */
export function useFocusNextHelper(onLastEntered?: () => void): FocusSuite {

  const idx2Elements: Record<number, any> = reactive({})

  const regRef = function (el: any, index: number) {
    if(el) {
      idx2Elements[index] = el
    }
    else{
      delete idx2Elements[index]
    }
  }

  // 按照设定的index，给各个元素的index排个序,结果如: [1, 2, 4, 5]，由于_.sortBy出来的结果是[string]，所以需要map成[number]
  const indexArray = computed(() => _.map(_.sortBy(_.keys(idx2Elements), o => parseInt(o)), l=>parseInt(l)))

  const onEntered = function (index: number) {
    let idx = _.indexOf(indexArray.value, index)
    if (idx !== -1) {
      for (; idx + 1 < indexArray.value.length; idx++) {
        const theNextComponent = idx2Elements[indexArray.value[idx + 1]]
        if (typeof (theNextComponent.focus) === 'function') {
          if (theNextComponent.readonly || theNextComponent.disable) {
            continue
          }
          void nextTick().then(() => {
            theNextComponent.focus()
          })
          break
        }
      }
      if (idx + 1 == indexArray.value.length) {
        if (onLastEntered) {
          onLastEntered()
        }
      }
    }
  }

  const focusFirst = function () {
    for (let idx = 0; idx + 1 < indexArray.value.length; idx++) {
      const theComponent = idx2Elements[indexArray.value[idx]]
      if (typeof (theComponent.focus) === 'function') {
        if (theComponent.readonly || theComponent.disable) {
          continue
        }
        void nextTick().then(() => {
          theComponent.focus()
        })
        break
      }
    }
  }

  return {
    regRef,
    onEntered,
    focusFirst
  } as FocusSuite
}
